<template>
  <div class="s-canvas" @click="changeCode" style="cursor: pointer;">
    <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const props = defineProps({
  modelValue: String,
  fontSizeMin: {
    type: Number,
    default: 25
  },
  fontSizeMax: {
    type: Number,
    default: 35
  },
  backgroundColorMin: {
    type: Number,
    default: 200
  },
  backgroundColorMax: {
    type: Number,
    default: 220
  },
  dotColorMin: {
    type: Number,
    default: 60
  },
  dotColorMax: {
    type: Number,
    default: 120
  },
  contentWidth: {
    type: Number,
    default: 150
  },
  contentHeight: {
    type: Number,
    default: 50
  }
})

const emit = defineEmits(['update:modelValue'])

const identifyCode = ref('')
const identifyCodes = '1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'

const randomNum = (min, max) => Math.floor(Math.random() * (max - min) + min)
const randomColor = (min, max) => `rgb(${randomNum(min, max)},${randomNum(min, max)},${randomNum(min, max)})`

const drawPic = () => {
  const canvas = document.getElementById('s-canvas')
  const ctx = canvas.getContext('2d')
  ctx.textBaseline = 'bottom'
  
  // 绘制背景
  ctx.fillStyle = randomColor(props.backgroundColorMin, props.backgroundColorMax)
  ctx.fillRect(0, 0, props.contentWidth, props.contentHeight)
  
  // 绘制文字
  for (let i = 0; i < identifyCode.value.length; i++) {
    drawText(ctx, identifyCode.value[i], i)
  }
  
  drawLine(ctx)
  drawDot(ctx)
}

const drawText = (ctx, txt, i) => {
  ctx.fillStyle = randomColor(50, 160)
  ctx.font = `${randomNum(props.fontSizeMin, props.fontSizeMax)}px SimHei`
  
  const x = (i + 1) * (props.contentWidth / (identifyCode.value.length + 1))
  const y = randomNum(props.fontSizeMax, props.contentHeight - 5)
  const deg = randomNum(-30, 30)
  
  ctx.translate(x, y)
  ctx.rotate(deg * Math.PI / 180)
  ctx.fillText(txt, 0, 0)
  ctx.rotate(-deg * Math.PI / 180)
  ctx.translate(-x, -y)
}

const drawLine = (ctx) => {
  for (let i = 0; i < 4; i++) {
    ctx.strokeStyle = randomColor(100, 200)
    ctx.beginPath()
    ctx.moveTo(randomNum(0, props.contentWidth), randomNum(0, props.contentHeight))
    ctx.lineTo(randomNum(0, props.contentWidth), randomNum(0, props.contentHeight))
    ctx.stroke()
  }
}

const drawDot = (ctx) => {
  for (let i = 0; i < 30; i++) {
    ctx.fillStyle = randomColor(0, 255)
    ctx.beginPath()
    ctx.arc(randomNum(0, props.contentWidth), randomNum(0, props.contentHeight), 1, 0, 2 * Math.PI)
    ctx.fill()
  }
}

const makecode = (len) => {
  identifyCode.value = ''
  for (let i = 0; i < len; i++) {
    identifyCode.value += identifyCodes[randomNum(0, identifyCodes.length)]
  }
}

const changeCode = () => {
  makecode(4)
  emit('update:modelValue', identifyCode.value)
  drawPic()
}

defineExpose({ changeCode })

onMounted(() => {
  // changeCode()
})
</script>

<style scoped>
.s-canvas {
  display: inline-block;
}
</style>
